/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.chain;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import tal.drivechain.chain.script.ScriptCommand;

/**
 *
 * @author Main
 */
public abstract class RolePatcher extends Patcher {
    protected List<String> inputNames = new ArrayList<String>();
    protected List<String> outputNames = new ArrayList<String>();
    protected List<String> parserNames = new ArrayList<String>();
    protected List<ChainNode> parsers = new ArrayList<ChainNode>();
    protected List<ChainNode> inputs = new ArrayList<ChainNode>();
    protected List<ChainNode> outputs = new ArrayList<ChainNode>();
    
    public void configure(List<ScriptCommand> configuration) {
        inputNames.clear(); outputNames.clear(); parserNames.clear();
        for (ScriptCommand command : configuration) {
            if (command!=null && command.getArgCount()>=2) {
                String typeName = command.getName();
                String modules = command.getArg1() + " " + command.getArg2();
                if (typeName.equals("input"))
                    inputNames.add(modules);
                else if (typeName.equals("output"))
                    outputNames.add(modules);
                else if (typeName.equals("parser"))
                    parserNames.add(modules);
                else throw new IllegalArgumentException("Invalid script command: " + typeName);
            } else 
                throw new IllegalArgumentException("Invalid script command: " + command);
        }
    }
    
    protected void fetchModules(Chain chain) throws AbortChainException {
        for (String parserName : parserNames) {
            parsers.addAll(getNodes(parserName, chain));
        } for (String inputName : inputNames) {
            inputs.addAll(getNodes(inputName, chain));
        } for (String outputName : outputNames) {
            outputs.addAll(getNodes(outputName, chain));
        }
    }
    
    protected List<ChainNode> getNodes(String nodes, Chain chain) throws AbortChainException {
        List<ChainNode> outs = new ArrayList<ChainNode>();
        nodes = nodes.trim();
        StringTokenizer tokenizer = new StringTokenizer(nodes, ",");
        while (tokenizer.hasMoreTokens()) {
            String name = tokenizer.nextToken().trim();
            ChainNode out = getNode(name, chain);
            outs.add(out);
        }
        return outs;
    }

    @Override
    public boolean isPatcherCommand(ScriptCommand command) {
        return (command.getName().equals("input") || command.getName().equals("output") || command.getName().equals("parser"));
    }

    @Override
    public void executePatchCommand(Chain chain, ScriptCommand command) throws IllegalArgumentException, AbortChainException {
        List<ScriptCommand> commands = new ArrayList<ScriptCommand>();
        commands.add(command);
        configure(commands);
        patchNodes(chain);
    }


}
